#pragma once

#include <iostream>
#include <string>
#include <map>
#include <vector>
using namespace std;


class Word {
public:
	int typenum;//种别码
	string word;//保留字
public:
	Word();
};
Word::Word() {
	typenum = 0;
	word = "null";
}

class Lexical_Analysis {
public:
	string input;//输入缓冲
	string token;//单词缓冲
	char ch;//当前字符
	int p_input;//输入指针
	int p_token;//单词缓冲指针
	map<string, int> Species_Code_Map;
	vector<Word> result;

public:
	Lexical_Analysis(string);
	void Init_Species_Code_Map();
	char get_ch();
	void Remove_Blank();
	bool letter();//ch是否是字母
	bool digit();//ch是否是数字
	void retract();//指针回退
	Word scaner();//扫描函数
	void concat();//字符串拼接
	int reserve();
	void out_display();
};

//源程序用来初始化LA
Lexical_Analysis::Lexical_Analysis(string source_program) {
	input = source_program;
	Init_Species_Code_Map();//初始化种别码字典
}

void Lexical_Analysis::Init_Species_Code_Map(){
	Species_Code_Map.insert(pair<string, int>("begin", 1));
	Species_Code_Map.insert(pair<string, int>("if", 2));
	Species_Code_Map.insert(pair<string, int>("then", 3));
	Species_Code_Map.insert(pair<string, int>("while", 4));
	Species_Code_Map.insert(pair<string, int>("do", 5));
	Species_Code_Map.insert(pair<string, int>("end", 6));



	//未完待续...
}

//读取一个字符
char Lexical_Analysis::get_ch() {
	ch = input[p_input];
	p_input++;//输入指针递增
	return ch;
}

void Lexical_Analysis::Remove_Blank() {
	while (ch == ' ') {
		ch = input[p_input];
		p_input++;
	}
}

bool Lexical_Analysis::letter() {
	if (ch >= 'a'&&ch <= 'z' || ch >= 'A'&&ch <= 'Z')
		return 1;
	else
		return 0;
}

bool Lexical_Analysis::digit() {
	if (ch >= '0'&&ch <= '9')
		return 1;
	else
		return 0;
}

void Lexical_Analysis::retract()
{
	p_input = p_input - 1;
}
void Lexical_Analysis::concat()
{
	token=token+ch;
	p_token++;
}

//通过已识别的单词获取种别码
int Lexical_Analysis::reserve()
{
	if (Species_Code_Map.find(token) == Species_Code_Map.end())
	{
		return 10;//自定义符号种别码		
	}
	return Species_Code_Map[token];
}

void Lexical_Analysis::out_display()
{
	cout << "词法分析结果：";
	for (int i = 0; i < result.size(); i++) {
		cout << "(";
		cout << result[i].typenum;
		cout << ",";
		cout << result[i].word;
		cout << ")";
	}
	cout << endl;

}

Word Lexical_Analysis::scaner() {
	get_ch();
	Remove_Blank();
	Word W;

	//模式1：拼字符串
	if (letter()) {
		//如果是字母或数字
		while (letter() || digit()) {
			concat();
			get_ch();
		}
		retract();//指针回退
		W.typenum = reserve();
		W.word = token;
		result.push_back(W);//识别出的单词加入结果数组
		token = "";
		return W;
	}

	//模式2：拼数字模式
	if (digit())
	{
		int flag = 0;
		while (digit()||ch=='.') {
			if (ch == '.')
				flag = 1;//有小数点
			concat();
			get_ch();
		}
		retract();
		W.typenum = 11;
		if (flag == 1)
			W.typenum = 12;
		W.word = token;
		result.push_back(W);//识别出的数字加入结果数组
		token = "";
		return W;
	}

	//模式3：拼运算符、界符
	if (!(digit() || letter()))
	{
		switch (ch) {
		case'=':

			get_ch();
			if (ch == '=') {
				W.typenum = 39;
				W.word = "==";
				
				return W;
			}
			retract();
			W.typenum = 25;
			W.word = "=";

			result.push_back(W);//识别出的符号加入结果数组

			return W;
			break;
		case'+':
			W.typenum = 13;
			W.word = "+";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'-':
			W.typenum = 14;
			W.word = "-";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'*':
			W.typenum = 15;
			W.word = "*";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'/':
			W.typenum = 16;
			W.word = "/";
			return W;
			break;
		case'(':
			W.typenum = 27;
			W.word = "(";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case')':
			W.typenum = 28;
			W.word = ")";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'[':
			W.typenum = 28;
			W.word = "[";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case']':
			W.typenum = 29;
			W.word = "]";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'{':
			W.typenum = 30;
			W.word = "{";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'}':
			W.typenum = 31;
			W.word = "}";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case',':
			W.typenum = 32;
			W.word = ",";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case':':
			get_ch();
			if (ch == '=') {
				W.typenum = 18;
				W.word = ":=";
				result.push_back(W);//识别出的符号加入结果数组
				return W;
			}
			retract();
			W.typenum = 17;
			W.word = ":";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case';':
			W.typenum = 26;
			W.word = ";";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'>':
			get_ch();
			if (ch == '=') {
				W.typenum = 24;
				W.word = ">=";
				result.push_back(W);//识别出的符号加入结果数组
				return W;
			}
			retract();
			W.typenum = 23;
			W.word = ">";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'<':
			get_ch();
			if (ch == '=') {
				W.typenum = 22;
				W.word = "<=";
				result.push_back(W);//识别出的符号加入结果数组
				return W;
			}
			else if (ch == '>') {
				W.typenum = 21;
				W.word = "<>";
			}
			retract();
			W.typenum = 20;
			W.word = "<";
			result.push_back(W);//识别出的符号加入结果数组
			return W;
			break;
		case'!':
			get_ch();
			if (ch == '=') {
				W.typenum = 40;
				W.word = "!=";
				result.push_back(W);//识别出的符号加入结果数组
				return W;
			}
			retract();
			W.typenum = -1;
			W.word = "ERROR";
			return W;
			break;
		case'\0':
			W.typenum = 1000;
			W.word = "OVER";
			return W;
			break;
		default:
			W.typenum = 0;
			W.word = "#";
			return W;

			return W;

		}
	}
	
}